%--------------------------------------------------------------------------------
% FFT regression test program
% arg: comprehensive = 1 for full random vector sweep (default is 0) 
%--------------------------------------------------------------------------------
function fft_tst(comprehensive)
  if nargin <1
    % set to 1 for full random vector sweep over all valid vector sizes
    comprehensive=0;  
  end
                       

% setup some extra parameters for my fft function fft_r2dt()
%--------------------------------------------------------------------------------
inverse=1;
forward=0;
strict=1;
no_strict=0;
debug = 1;
no_debug = 0;

disp('Info: Begin regression test');
%--------------------------------------------------------------------------------
disp('Info: Verifying vector of 32 digits of Pi - fft_r2dt() versus native fft()');
pi32_str = '31415926535897932384626433832795';
pi32_vec = [];
for k=1:32
  pi32_vec = [pi32_vec str2num(pi32_str(k))];
end
disp('Info: input data vector:'); pi32_vec
pi32_vec_fft_r2dt = fft_r2dt(pi32_vec, forward, debug, strict); 
pi32_vec_fft = fft(pi32_vec);
pi32_vec_fft_diff = pi32_vec_fft_r2dt - pi32_vec_fft;
disp('Info: output data vector: '); pi32_vec_fft_r2dt
disp('Info: sum of absolute differences with respect to reference fft()');
abs_err_sum = sum(abs(pi32_vec_fft_diff))

%--------------------------------------------------------------------------------
% Sweep input random vectors of size 2^0 to 2^10 and compare
% outputs to native Matlab FFT reference
%--------------------------------------------------------------------------------
fail_count=0;
test_count=0;
error_tolerance = 1e-9;
num_vectors_per_length = 64;
log_size_range = 0:10;

if comprehensive ~= 0
disp('Info: Comprehensive randomized verification:');  
disp('Info: 1) forward fft_r2dt(x) matches native fft(x)');
disp('Info: 2) inv_fft_r2dt{fft_r2dt(x)} matches original x');

for l=log_size_range
  n = 2^l;
  for m=1:num_vectors_per_length
    test_count = test_count+2;

    x = rand(1,n);
    
%    str = sprintf('Testing random vector #%d with N=%d',test_count,n);
%    disp(str); 
    
    % dut is 'design implementation under test'
    xf_dut = fft_r2dt(x,forward, no_debug, no_strict); 

    % ref is 'reference implementation - native FFT'    
    xf_ref = fft(x);           

    xf_diff = xf_dut - xf_ref;
    sum_diff = sum(abs(xf_diff));

    % check for both for excess absolute error and grossly invalid results
    if sum_diff < error_tolerance || sum_diff == NaN
%      disp('Pass: fft_dit(x) matches fft(x) reference within error tolerance');
    else
      str = sprintf('Fail: fft_r2dt(x) does not match fft(x) - size: %d', n);      
      disp(str);
      sum_diff
      fail_count=fail_count+1
    end
    
    % check that inverse of FFT matches original
    xf_dut_inv = fft_r2dt(xf_dut,inverse,no_debug,no_strict);
    x_diff = x - xf_dut_inv;
    sum_diff = sum(abs(x_diff));

    % check for both for excess absolute error and grossly invalid results
    if sum_diff < error_tolerance || sum_diff == NaN
      % disp('Pass: inverse test');
    else
      str = sprintf('Fail: inv(fft_r2dt(x)) does not equal x - size: %d', n);      
      disp(str);
      sum_diff
      fail_count=fail_count+1
    end
    
  end
end
l =log_size_range(1);
u =log_size_range(length(log_size_range));
str = sprintf('Info:   log(size) range %d to %d, %d instances each',l,u,num_vectors_per_length);
disp(str);     
str = sprintf('Info:   %d vectors run, %d vectors failed', test_count, fail_count);
disp(str);     

end

disp('Info: End regression test');


